package essential.ch3;

import java.util.HashMap;
import java.util.Map;

/**
 * @Date 2021/10/23
 * @Created by Jonathan
 * 如果一个类重写了equals方法，那么该类也一定要重写hashCode方法
 * <p>
 * 默认情况下，也就是从Object类中继承而来的equals方法与‘==’是完全等价的，也就是比较的是对象在内存中的地址。
 * 但是我们可以重写equals方法，使其按照我们需要的方式进行比较，例如String类重写了equals方法，
 * 使其比较的是字符序列，而不再是内存地址。”一般回答这些就可以了，如果还想再深入一点，
 * 那可以继续补充：“在重写equals方法的时候，需要遵守equals方法的几点特性，
 * 即自反性、对称性、传递性、一致性、与null值的比较。并且在重写equals方法的同时，
 * 也一定要重写hashCode方法，另外也要遵守hashCode API文档中的规定。”
 */
public class AbnormalResult2 {
    public static void main(String[] args) {
        Map<String, Value> map1 = new HashMap<>();
        String s1 = new String("key");
        String s2 = new String("key");
        Value value = new Value(15);
        map1.put(s1, value);
        //map1.put(s2, value);
        System.out.printf("ret:%s %s", s1.equals(s2), s2.equals(s1));
        System.out.printf("\nmap1.get(s1):%s, map1.get(s2):%s", map1.get(s1), map1.get(s2));
        Map<Key, Value> map2 = new HashMap<>();
        Key k1 = new Key("A");
        Key k2 = new Key("A");
        map2.put(k1, value);
        //map2.put(k2, value);
        System.out.printf("\nret:%s", k1.equals(k2));
        System.out.printf("\nmap2.get(k1):%s, map2.get(k2):%s", map2.get(k1), map2.get(k2));
    }
}

class Key {
    private String k;

    public Key(String k) {
        this.k = k;
    }

    /**
     * 如果两个Key类对象的变量k相等，则认为两个Key对象相等，并返回true，否则返回false
     *
     * @param o
     * @return
     */
    @Override
    public boolean equals(Object o) {
        if (o instanceof Key) {
            Key key = (Key) o;
            return key.k.equals(k);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return k.hashCode();
    }
}

class Value {
    private int v;

    public Value(int v) {
        this.v = v;
    }

    @Override
    public String toString() {
        return "Value[" + "v=" + v + ']';
    }
}



